﻿using Mapster;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Nantianmen.Core.Services;
using Nantianmen.Domain.Dtos;
using Nantianmen.Shared;

namespace Nantianmen.Endpoints.Routes
{
    public class RouteManagementEndpoints : IEndpoint
    {
        public IEndpointRouteBuilder MapEndpoints(IEndpointRouteBuilder builder)
        {
            var group = builder.MapGroup("/routes")
                .WithParameterValidation()
                .WithOpenApi()
                .WithTags("Routes");

            group.MapGet("/all",
                async (IRouteService routeService) =>
                {
                    var routes = await routeService.ListRoutesAsync();
                    return routes.Select(r => r.Adapt<RouteDto>()).OrderByDescending(x => x.UpdatedAt).ToList();
                })
                .WithName("Routes_ListAll");

            group.MapGet("/detail/{id}",
                async (string id, IRouteService service) =>
                {
                    var route = await service.FindByIdAsync(id);
                    return route?.Adapt<RouteDto>();
                })
                .WithName("Routes_Detail");

            group.MapPost("/create", async (CreateRouteRequest request, IRouteService service) =>
            {
                var route = request.Adapt<Domain.Models.Route>();
                var result = await service.CreateAsync(route);
                return result;
            }).WithName("Routes_Create");

            group.MapPost("/update", async (UpdateRouteRequest request, IRouteService service, NantianmenErrorDescriber errorDescriber) =>
            {
                var current = await service.FindByIdAsync(request.Id);

                if(current is null)
                {
                    return NantianmenResult.Failed(errorDescriber.RouteNotFound(request.Id));
                }

                current.ClusterId = request.ClusterId;
                current.Order = request.Order;
                current.Match = request.Match;
                current.MaxRequestBodySize = request.MaxRequestBodySize;
                current.CorsPolicy = request.CorsPolicy;
                current.AuthorizationPolicy = request.AuthorizationPolicy;
                current.Metadata = request.Metadata;
                current.Transforms = request.Transforms;

                var result = await service.UpdateAsync(current);

                return result;
            }).WithName("Routes_Update");

            group.MapPost("/remove/{id}", async (string id, IRouteService service) =>
            {
                return await service.RemoveAsync(id);
            }).WithName("Routes_Remove");

            return builder;
        }
    }
}
